import cv2
import threading
from typing import Dict, Optional, List
import numpy as np
import time
from config.settings import CAMERA_SCAN_TIMEOUT

class Camera:
    def __init__(self, camera_id: int):
        self.camera_id = camera_id
        self.cap = None
        self.running = False
        self.frame = None
        self.lock = threading.Lock()
        self.capture_thread = None
        self.retry_count = 0
        self.max_retries = 3
        
    def start(self) -> bool:
        try:
            # 先尝试默认后端
            self.cap = cv2.VideoCapture(self.camera_id)
            if not self.cap.isOpened():
                # 如果默认后端失败，尝试 DSHOW
                self.cap = cv2.VideoCapture(self.camera_id, cv2.CAP_DSHOW)
                
            if not self.cap.isOpened():
                print(f"摄像头连接错误: 无法打开摄像头 {self.camera_id}")
                return False
                
            # 设置属性
            self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
            self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
            self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
            
            # 读取测试帧
            ret, frame = self.cap.read()
            if not ret or frame is None:
                print(f"摄像头 {self.camera_id} 无法读取视频帧")
                return False
                
            self.running = True
            self.capture_thread = threading.Thread(target=self._capture_loop)
            self.capture_thread.daemon = True
            self.capture_thread.start()
            return True
            
        except Exception as e:
            print(f"摄像头启动错误: {e}")
            if self.cap:
                self.cap.release()
                self.cap = None
            return False
            
    def is_opened(self) -> bool:
        return self.cap is not None and self.cap.isOpened()

    def stop(self):
        self.running = False
        if self.capture_thread:
            self.capture_thread.join(timeout=1.0)
        if self.cap:
            self.cap.release()

    def _capture_loop(self):
        while self.running:
            try:
                if not self.cap or not self.cap.isOpened():
                    print(f"摄像头 {self.camera_id} 连接已断开")
                    break
                    
                ret, frame = self.cap.read()
                if ret and frame is not None:
                    with self.lock:
                        self.frame = frame
                        self.retry_count = 0
                else:
                    self.retry_count += 1
                    if self.retry_count >= self.max_retries:
                        print(f"摄像头 {self.camera_id} 连续 {self.max_retries} 次读取失败")
                        break
                    time.sleep(0.1)
                    
            except Exception as e:
                print(f"摄像头 {self.camera_id} 捕获错误: {e}")
                break
                
        self.running = False

    def get_frame(self) -> Optional[np.ndarray]:
        with self.lock:
            return self.frame.copy() if self.frame is not None else None

class CameraManager:
    def __init__(self):
        self.cameras: Dict[int, Optional[Camera]] = {i: None for i in range(8)}
        self._initialized = False  # 添加初始化标志
        
    def init_cameras(self) -> None:
        """初始化所有摄像头位置"""
        if self._initialized:  # 避免重复初始化
            print("摄像头管理器已经初始化")
            return
            
        for camera_id in range(8):
            try:
                if self.add_camera(camera_id):
                    print(f"摄像头 {camera_id} 初始化成功")
                else:
                    print(f"摄像头 {camera_id} 初始化失败")
                time.sleep(0.1)
            except Exception as e:
                print(f"初始化摄像头 {camera_id} 时出错: {e}")
                continue
                
        self._initialized = True

    def add_camera(self, camera_id: int) -> bool:
        if not 0 <= camera_id < 8:
            print(f"摄像头ID {camera_id} 超出范围(0-7)")
            return False
            
        if self.cameras[camera_id] is not None:
            print(f"摄像头位置 {camera_id} 已被占用")
            return False
            
        camera = Camera(camera_id)
        if not camera.start():
            self.cameras[camera_id] = None
            return False
            
        self.cameras[camera_id] = camera
        print(f"摄像头 {camera_id} 已启动")
        return True

    def remove_camera(self, camera_id: int) -> bool:
        if not 0 <= camera_id < 8:
            print(f"摄像头ID {camera_id} 超出范围(0-7)")
            return False
            
        camera = self.cameras[camera_id]
        if camera is None:
            print(f"摄像头位置 {camera_id} 未使用")
            return False
            
        camera.stop()
        self.cameras[camera_id] = None
        print(f"摄像头 {camera_id} 已停止")
        return True

    def get_all_cameras(self) -> Dict[int, Optional[Camera]]:
        return self.cameras

    def get_camera(self, camera_id: int) -> Optional[Camera]:
        if not 0 <= camera_id < 8:
            return None
        return self.cameras.get(camera_id)
  